package com.bajiao.app.controller.store;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.qrcode.QrCodeUtil;
import cn.hutool.extra.qrcode.QrConfig;
import com.alibaba.fastjson.JSONObject;
import com.bajiao.app.base.AppBaseController;
import com.bajiao.common.api.vo.RestResult;
import com.bajiao.common.aspect.annotation.Idempotent;
import com.bajiao.common.constant._Whole;
import com.bajiao.common.exception.DataHandleException;
import com.bajiao.common.util.FastJsonHelper;
import com.bajiao.common.util.encryption.AesEncryptUtil;
import com.bajiao.common.util.oConvertUtils;
import com.bajiao.common.web.entity.TableDataInfo;
import com.bajiao.dto.store.*;
import com.bajiao.entity.config.Config;
import com.bajiao.entity.store.Store;
import com.bajiao.entity.store.StoreApply;
import com.bajiao.entity.store.StoreUser;
import com.bajiao.entity.user.UserCoupon;
import com.bajiao.service.order.CouponOrderService;
import com.bajiao.service.order.OrderService;
import com.bajiao.service.reserve.ReserveService;
import com.bajiao.service.store.StoreApplyService;
import com.bajiao.service.store.StoreService;
import com.bajiao.service.store.StoreUserService;
import com.bajiao.service.user.UserCouponService;
import com.bajiao.vo.reserve.ReserveResponse;
import com.bajiao.vo.store.*;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.crypto.IllegalBlockSizeException;
import java.security.GeneralSecurityException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
@Api(tags = "微众通店铺接口")
@RestController
@RequestMapping("/api/v1/wzt/store")
public class RestWztStoreController extends AppBaseController {

    @Resource
    private StoreService storeService;
    @Resource
    private StoreUserService storeUserService;
    @Resource
    private OrderService orderService;
    @Resource
    private UserCouponService userCouponService;
    @Resource
    private StoreApplyService storeApplyService;
    @Resource
    private ReserveService reserveService;

    @PostMapping(value = "/set/status")
    @ApiOperation(value = "修改店铺状态")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "storeId", value = "店铺id", dataType = "String", required = true),
            @ApiImplicitParam(name = "status", value = "1-营业 2-休息", required = true, dataType = "Integer")
    })
    public RestResult setStatus(@ModelAttribute("storeUser") StoreUser storeUser,
                                @RequestParam("status") Integer status) {
        if (ObjectUtil.isNull(storeUser))
            return tokenOverdue();
        if (status < 1 || status > 2)
            throw new DataHandleException("店铺状态异常");
        //@create by FanJq 2024/12/26 11:30 更新店铺状态
        storeService.lambdaUpdate().set(Store::getStatus, status).eq(Store::getId, storeUser.getStoreId()).update();
        return success();
    }

    @PostMapping(value = "/scan/code")
    @ApiOperation(value = "扫码核销")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "encipher", value = "二维码内容", dataType = "String", required = true)
    })
    public RestResult scanCode(@ModelAttribute("storeUser") StoreUser storeUser,
                               @RequestParam("encipher") String encipher) {
        if (ObjectUtil.isNull(storeUser))
            return tokenOverdue();
        //@create by FanJq 2024/12/26 12:00 验证权限
        storeUserService.verifyPermission(storeUser.getPermission(), "scan");
        String jsonStr = "";
        try {
            jsonStr = AesEncryptUtil.desEncrypt(encipher);
        } catch (Exception e) {
            throw new DataHandleException("未获取到核销信息");
        }
        JSONObject json = JSONObject.parseObject(jsonStr);
        String type = json.getString("a");
        String verifyCode = json.getString("b");
        if (StrUtil.hasBlank(type, verifyCode))
            throw new DataHandleException("未获取到核销信息");
        if (StrUtil.equals(type, "product")) {
            //@create by FanJq 2024/12/26 14:29 产品劵核销
            String orderNo = orderService.scanCode(storeUser.getStoreId(), verifyCode);
            return success(orderNo);
        } else if (StrUtil.equals(type, "coupon")) {
            //@create by FanJq 2024/12/26 14:29 优惠券核销
            UserCoupon userCoupon = userCouponService.getByVerifyCode(verifyCode);
            //@create by FanJq 2024/12/26 14:49 验证优惠券状态
            if (ObjectUtil.isNull(userCoupon))
                throw new DataHandleException("未找到优惠券信息，核销失败");
            if (userCoupon.getStatus() != _Whole.ONE)
                throw new DataHandleException("优惠券状态异常，无法核销");
            if (userCoupon.getScope() != _Whole.TWO || !StrUtil.equals(storeUser.getStoreId(), userCoupon.getStoreId()))
                throw new DataHandleException("非商家优惠券，核销失败");
            //@create by FanJq 2024/12/26 14:48 开始核销
            userCouponService.useCoupon(userCoupon, _Whole.THREE);
            return success();
        } else
            throw new DataHandleException("未获取到核销信息");
    }

    @GetMapping(value = "/details")
    @ApiOperation(value = "门店详情")
    public RestResult<StoreDetailsResponse> getStoreDetails(@ModelAttribute("storeUser") StoreUser storeUser) {
        if (ObjectUtil.isNull(storeUser))
            return tokenOverdue();
        Store store = storeService.getById(storeUser.getStoreId());
        StoreDetailsResponse response = FastJsonHelper.beanToBean(store, StoreDetailsResponse.class);
        response.setSliderImageList(Arrays.asList(response.getSliderImage().split(StringPool.COMMA)));
        return success(response);
    }

    @PostMapping(value = "/modify")
    @ApiOperation(value = "修改门店信息")
    public RestResult<StoreDetailsResponse> modifyStoreInfo(@ModelAttribute("storeUser") StoreUser storeUser,
                                                            StoreEditRequest request) {
        if (ObjectUtil.isNull(storeUser))
            return tokenOverdue();
        //@create by FanJq 2024/12/26 12:00 验证权限
        storeUserService.verifyPermission(storeUser.getPermission(), "storeSet");
        storeService.modifyStoreInfo(storeUser.getStoreId(), request);
        return success();
    }

    @GetMapping(value = "/financial")
    @ApiOperation(value = "门店财务数据")
    public RestResult<StoreStatResponse> getStoreFinancial(@ModelAttribute("storeUser") StoreUser storeUser) {
        if (ObjectUtil.isNull(storeUser))
            return tokenOverdue();
        storeUserService.verifyPermission(storeUser.getPermission(), "finance");
        StoreStatResponse response = storeService.getStoreFinancial(storeUser.getStoreId());
        return success(response);
    }

    @GetMapping(value = "/financial/total")
    @ApiOperation(value = "门店总营业额", notes = "totalAmount-总核销面额，totalNum-总核销券数量")
    public RestResult getStoreTotalFinancial(@ModelAttribute("storeUser") StoreUser storeUser) {
        if (ObjectUtil.isNull(storeUser))
            return tokenOverdue();
        storeUserService.verifyPermission(storeUser.getPermission(), "storeBill");
        Map<String, String> response = storeService.getStoreTotalFinancial(storeUser.getStoreId());
        return success(response);
    }

    @GetMapping(value = "/order/page")
    @ApiOperation(value = "门店商品订单")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "pageNum", value = "页码", defaultValue = "1", dataType = "Integer", required = true),
            @ApiImplicitParam(name = "pageSize", value = "每页条数", defaultValue = "10", dataType = "Integer", required = true)
    })
    public RestResult<TableDataInfo<StoreOrderResponse>> getStoreOrderPage(@ModelAttribute("storeUser") StoreUser storeUser) {
        if (ObjectUtil.isNull(storeUser))
            return tokenOverdue();
        startPage();
        storeUserService.verifyPermission(storeUser.getPermission(), "storeBill");
        List<StoreOrderResponse> responseList = storeService.getStoreOrderPage(storeUser.getStoreId());
        return success(getDataTable(responseList));
    }

    @GetMapping(value = "/coupon/order/page")
    @ApiOperation(value = "门店优惠券订单")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "pageNum", value = "页码", defaultValue = "1", dataType = "Integer", required = true),
            @ApiImplicitParam(name = "pageSize", value = "每页条数", defaultValue = "10", dataType = "Integer", required = true)
    })
    public RestResult<TableDataInfo<StoreCouponOrderResponse>> getStoreCouponOrderPage(@ModelAttribute("storeUser") StoreUser storeUser) {
        if (ObjectUtil.isNull(storeUser))
            return tokenOverdue();
        startPage();
        storeUserService.verifyPermission(storeUser.getPermission(), "storeBill");
        List<StoreCouponOrderResponse> responseList = storeService.getStoreCouponOrderPage(storeUser.getStoreId());
        return success(getDataTable(responseList));
    }

    @GetMapping(value = "/aptitude")
    @ApiOperation(value = "资质认证")
    public RestResult<StoreApplyResponse> getStoreAptitude(@ModelAttribute("storeUser") StoreUser storeUser) {
        if (ObjectUtil.isNull(storeUser))
            return tokenOverdue();
        StoreApply storeApply = storeApplyService.getByStoreId(storeUser.getStoreId());
        StoreApplyResponse response = FastJsonHelper.beanToBean(storeApply, StoreApplyResponse.class);
        return success(response);
    }

    @GetMapping(value = "/user/list")
    @ApiOperation(value = "获取子账号列表")
    public RestResult<List<StoreUserResponse>> getStoreUserList(@ModelAttribute("storeUser") StoreUser storeUser) {
        if (ObjectUtil.isNull(storeUser))
            return tokenOverdue();
        if (storeUser.getType().intValue() != _Whole.ONE)
            throw new DataHandleException("非店铺主账号，无权限查看");
        List<StoreUserResponse> storeUserList = storeUserService.getStoreUserList(storeUser.getStoreId());
        return success(storeUserList);
    }

    @PostMapping(value = "/user/create")
    @ApiOperation(value = "创建子账号")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "account", value = "账号", dataType = "String", required = true),
            @ApiImplicitParam(name = "password", value = "密码", dataType = "String", required = true)
    })
    public RestResult createUser(@ModelAttribute("storeUser") StoreUser storeUser,
                                 @RequestParam("account") String account,
                                 @RequestParam("password") String password) {
        if (ObjectUtil.isNull(storeUser))
            return tokenOverdue();
        if (storeUser.getType().intValue() != _Whole.ONE)
            throw new DataHandleException("非店铺主账号，无权限创建");
        storeUserService.create(storeUser.getStoreId(), account, password, _Whole.TWO);
        return success();
    }

    @PostMapping(value = "/modify/permission")
    @ApiOperation(value = "修改子账号权限")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "账户id", dataType = "String", required = true),
            @ApiImplicitParam(name = "permissions", value = "权限code集合 多个,分割", dataType = "String", required = true)
    })
    public RestResult modifyPermission(@ModelAttribute("storeUser") StoreUser storeUser,
                                       @RequestParam("id") String id,
                                       @RequestParam("permissions") String permissions) {
        if (ObjectUtil.isNull(storeUser))
            return tokenOverdue();
        if (storeUser.getType().intValue() != _Whole.ONE)
            throw new DataHandleException("非店铺主账号，无权限修改");
        storeUserService.modifyPermission(storeUser.getStoreId(), id, permissions);
        return success();
    }

    @GetMapping(value = "/reserve/list")
    @ApiOperation(value = "获取预订记录")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "filterDate", value = "日期(年-月-日)", dataType = "String")
    })
    public RestResult<List<ReserveResponse>> getReserveList(@ModelAttribute("storeUser") StoreUser storeUser,
                                                            @RequestParam(value = "filterDate", required = false) String filterDate) {
        if (ObjectUtil.isNull(storeUser))
            return tokenOverdue();
        List<ReserveResponse> responseList = reserveService.getReserveList(storeUser.getStoreId(), filterDate);
        return success(responseList);
    }
}
